#include "svideowidget.h"
#include "ui_svideowidget.h"

#include <QAudioOutput>
#include <QVideoWidget>

#include <QPainter>
#include <QGraphicsBlurEffect>

#include <QMap>
#include <QThread>
#include <thread>

#include "toolutils.h"
#include "videoglwidget.h"

// music TODO:
// 1、专辑图片读取
// 2、音乐时长读取
// 3、音乐相关操作

SVideoWidget::SVideoWidget(QString filePath, QWidget* parent)
    : QWidget(parent)
    , mFilePath(filePath)
    , ui(new Ui::SVideoWidget)
{

    this->setAttribute(Qt::WA_DeleteOnClose);
    ui->setupUi(this);
    mPlayer = new QMediaPlayer(this);
    // this->setContentsMargins(10, 10, 10, 10);
    connect(this, &SVideoWidget::LoadMp3DataFinished, this, &SVideoWidget::LoadUi);
    connect(mPlayer, &QMediaPlayer::playingChanged, this, &SVideoWidget::DoPlayingChanged);
    connect(mPlayer, &QMediaPlayer::positionChanged, this, &SVideoWidget::DoPlayPostionChnaged);
    connect(mPlayer, &QMediaPlayer::loopsChanged, this, &SVideoWidget::DoPlayerLoopChanged);
    connect(mPlayer, &QMediaPlayer::sourceChanged, this, &SVideoWidget::DoPlayerSourceChanged);
    Init();
}

SVideoWidget::~SVideoWidget()
{
    delete ui;
}

QMediaPlayer* SVideoWidget::Player()
{
    return mPlayer;
}

QString SVideoWidget::PlayerType()
{
    return mPlayerType;
}

bool SVideoWidget::IsPlaying()
{
    return mPlayer->isPlaying();
}

bool SVideoWidget::IsLoop()
{
    return mPlayer->loops() == QMediaPlayer::Loops::Infinite ? true : false;
}

void SVideoWidget::PlayOrPause()
{
    if (!IsPlaying()) {
        mPlayer->play();
    } else {
        mPlayer->pause();
    }
}

qint64 SVideoWidget::GetTotalTime()
{
    return mPlayer->duration();
}

qint64 SVideoWidget::GetCurrentTime()
{
    return mPlayer->position();
}

float SVideoWidget::GetVolume()
{
    return mPlayer->audioOutput()->volume();
}

qreal SVideoWidget::GetRate()
{
    return mPlayer->playbackRate();
}

QUrl SVideoWidget::GetUrl()
{
    return mPlayer->source();
}

void SVideoWidget::SetPlayerPosition(qint64 position)
{
    mPlayer->setPosition(position);
}

void SVideoWidget::SetPlayerVolume(float volume)
{
    mPlayer->audioOutput()->setVolume(volume);
}

void SVideoWidget::SetPlayerRate(qreal rate)
{
    mPlayer->setPlaybackRate(rate);
}

void SVideoWidget::ChangePlayerLoop()
{
    mPlayer->setLoops(mPlayer->loops() == QMediaPlayer::Loops::Once ? QMediaPlayer::Loops::Infinite : QMediaPlayer::Loops::Once);
}

void SVideoWidget::DoPlayingChanged(bool isPlaying)
{
    emit PlayerStatusChanged(isPlaying);
}

void SVideoWidget::DoPlayPostionChnaged(qint64 position)
{
    emit PlayerPositionChanged(position);
}

void SVideoWidget::DoPlayerLoopChanged()
{
    emit PlayerLoopChanged(mPlayer->loops() == QMediaPlayer::Loops::Infinite ? true : false);
}

void SVideoWidget::DoPlayerVolumeChanged(float volume)
{
    emit PlayerVolumeChanged(volume);
}

void SVideoWidget::DoPlayerSourceChanged(const QUrl& media)
{
    emit PlayerSourceChanged(media);
}

void SVideoWidget::paintEvent(QPaintEvent *event)
{
    // 绘制 两个图层
    QWidget::paintEvent(event);

    if (!mLoadFinished) {
        return;
    }

    mMutex.lock();
    if (mAlbumImage.isNull() || mBackgroundImage.isNull()) {
        mMutex.unlock();
        return;
    }

    // 绘制层叠图片
    QPainter painter(this);
    painter.setCompositionMode(QPainter::CompositionMode_SourceOver);

    // 绘制背景图片
    painter.drawImage(
        5, 5,
        mBackgroundImage.scaled(
            rect().width() - 10, rect().height() - 10, Qt::IgnoreAspectRatio, Qt::SmoothTransformation)
    );

    // 绘制小图片
    painter.drawImage(10, rect().height() - 210,
        mAlbumImage.scaled(200, 200, Qt::IgnoreAspectRatio, Qt::SmoothTransformation));
    mMutex.unlock();
}

void SVideoWidget::LoadUi()
{
    mLoadFinished = true;
    update();
    // // 设置图片，之后可以搞成多线程异步的加载
    // ui->labelSongName->setText(mOtherMusicInfo.value("TITLE", ""));
    // ui->labelAlbumName->setText(mOtherMusicInfo.value("ALBUM", ""));
}

void SVideoWidget::Init()
{
    mPlayerType = ToolUtils::CheckFileType(mFilePath);
    if (mPlayerType == "video") {
        // 视频输出output
        // auto videoWidget = new QVideoWidget(this);
        auto videoWidget = new VideoGLWidget(this);
        mPlayer->setVideoSink(videoWidget->mVideoSink);
        // videoWidget->setGeometry(0, 0, 800, 600);
        // videoWidget->setWindowFlags(Qt::Widget);
        // WA_OpaquePaintEvent 减少渲染闪烁、提高性能
        videoWidget->setAttribute(Qt::WA_OpaquePaintEvent);
        // 双缓冲
        // videoWidget->setAutoFillBackground(true);
        // mPlayer->setVideoOutput(videoWidget);
        ui->horizontalLayout->addWidget(videoWidget);
    }
    // 音乐输出ouput
    auto audioOutput = new QAudioOutput(this);
    audioOutput->setVolume(1);
    mPlayer->setAudioOutput(audioOutput);
    connect(mPlayer->audioOutput(), &QAudioOutput::volumeChanged, this, &SVideoWidget::DoPlayerVolumeChanged);
    mPlayer->setSource(QUrl::fromLocalFile(mFilePath));
    // connect
    mPlayer->play();

    if (mPlayerType == "audio") {
        // 另起一个线程去执行费时操作
        std::thread thread([&]() {
            auto mp3Info = ToolUtils::ExtractInfoFromMP3(mFilePath);
            mMutex.lock();
            mAlbumImage = QImage::fromData(mp3Info.value("PICTURE", QByteArray()));
            mp3Info.remove("PICTURE");
            foreach (const auto key, mp3Info.keys()) {
                mOtherMusicInfo[key] = QString(mp3Info[key]);
            }
            mMutex.unlock();
            auto blurredImage = ToolUtils::GaussianBlur(
                mAlbumImage.scaled(200, 200, Qt::IgnoreAspectRatio, Qt::SmoothTransformation), 4, 4);
            QPainter imagePainter(&blurredImage);
            imagePainter.setCompositionMode(QPainter::CompositionMode_Multiply);
            constexpr auto color = QColor(100, 100, 100, 150); // darknessFactor 控制变暗的程度，范围从0到255
            imagePainter.fillRect(blurredImage.rect(), color);
            mMutex.lock();
            mBackgroundImage = std::move(blurredImage);
            mMutex.unlock();
            emit LoadMp3DataFinished();
        });
        thread.detach();
    }
}



// QImage adjustedImage = image.convertToFormat(QImage::Format_ARGB32);
// 通过QPainter直接修改image的亮度，叠加一个蒙版，这个方法感觉不错
// QPainter painter(&adjustedImage);
// painter.setCompositionMode(QPainter::CompositionMode_Difference);
// QColor color = QColor(0, 0, 0, 255); // darknessFactor 控制变暗的程度，范围从0到255
// painter.fillRect(adjustedImage.rect(), color);

// 修改rgb控制变暗的方法
// for (int y = 0; y < adjustedImage.height(); ++y) {
//     for (int x = 0; x < adjustedImage.width(); ++x) {
//         QRgb pixel = image.pixel(x, y);
//         int newR = qBound(0, qRed(pixel) - 100, 255);
//         int newG = qBound(0, qGreen(pixel) - 100, 255);
//         int newB = qBound(0, qBlue(pixel) - 100, 255);
//         adjustedImage.setPixel(x, y, qRgba(newR, newG, newB, qAlpha(pixel)));
//     }
// }

// 控件加上高斯模糊
// QGraphicsBlurEffect *blurEffect = new QGraphicsBlurEffect(this);
// blurEffect->setBlurRadius(50);
// ui->labelAlbumPicture->setGraphicsEffect(blurEffect);
//
